package lion.dev.web.useragent.parser;

import java.util.ArrayList;
import java.util.List;

import lion.dev.lang.KV;
import lion.dev.web.useragent.IUAParser;
import lion.dev.web.useragent.UserAgent;

import org.apache.commons.lang.StringUtils;

/**
 * @author lion
 * @email hl_0074@sina.com
 * @date 2014年6月4日
 */
public class BrowserParser implements IUAParser {

	private String name;
	private String type;

	public BrowserParser(String type) {

		this.type = type;
	}

	public BrowserParser(String name, String type) {

		this.name = name;
		this.type = type;
	}

	@Override
	public boolean visit(String token, UserAgent agent) {

		String oldName = agent.getBrowser();
		String bname = this.name;
		String bversion = null;
		int idx = token.indexOf('/');
		if (idx > 0) {
			if (this.name == null) {
				bname = token.substring(0, idx);
			}
			bversion = token.substring(idx + 1);
		} else {
			if (StringUtils.startsWith(token, this.name)) {
				bversion = token.substring(this.name.length()).trim();
			}
		}
		if (bname == null) {
			bname = token;
		}

		if (oldName != null) {
			if (comapre(bname, oldName) > 0) {
				setBrowser(bname, bversion, agent);
			}
		} else {
			setBrowser(bname, bversion, agent);
		}
		return true;
	}

	private int comapre(String browser1, String browser2) {

		int v1 = getBrowserWeight(browser1);
		int v2 = getBrowserWeight(browser2);
		return v1 - v2;
	}

	private int getBrowserWeight(String bname) {

		if (StringUtils.containsIgnoreCase(bname, "Internet Explore")) { return 0; }
		if (StringUtils.containsIgnoreCase(bname, "Safari")) { return 1; }
		if (StringUtils.containsIgnoreCase(bname, "Firefox")) { return 2; }
		if (StringUtils.containsIgnoreCase(bname, "Chrome")) { return 3; }
		if (StringUtils.equalsIgnoreCase(bname, "Opera")) { return 4; }
		if (StringUtils.containsIgnoreCase(bname, "Maxthon")) { return 6; }

		return 10;
	}

	private void setBrowser(String bname, String bversion, UserAgent agent) {

		agent.setBrowser(bname);
		agent.setBrowserVersion(bversion);
		agent.setType(type);

	}

	@Override
	public List<KV<String, String>> explain(String token) {

		List<KV<String, String>> result = new ArrayList<>();

		if (token.indexOf("/") == -1) {
			if (this.name != null && token.length() != this.name.length() && token.startsWith(this.name)) {
				result.add(new KV<>(this.name, "Browser Name"));
				result.add(new KV<>(token.substring(this.name.length()).trim(), "Browser version"));
			} else {
				result.add(new KV<>(token, "Browser Name"));
			}
		} else {
			String[] tokens = token.split("/");
			result.add(new KV<>(tokens[0], "Browser Name"));
			result.add(new KV<>(tokens[1], "Browser version"));
		}
		return result;
	}
}
